package com.jidolstar.astro
{
	/**
	 * 천문 좌표계 변환을 위한 클래스 <br>
	 * 
	 * <p>용어설명</p>
	 * <ul>
	 * 	<li>황도의 기울기(obliquity of the ecliptic) : 지구의 공전궤도(황도)와 천구의 적도사이의 각
	 * 	<li>위도(latitude) : 지구상의 관측지점의 위도
	 * 	<li>지방항성시(local hour angle) : 춘분점의 시간각=남중한별의 적경 
	 * 	<li>지평좌표계(horizontal coordinate system) : 
	 * 		관측지점 기준의 좌표계이다. 북점을 기준으로 천체의 발까지 동적으로 잰 각을 방위각(azimuth), 
	 * 		천체의 발부터 천체까지 잰각을 고도(altitude)라고 한다.
	 * 		일부 천문학자들은 북점이 아닌 남점을 기준으로 방위각을 재기도 한다.
	 * 		이 프로그램은 북점을 기준으로 한다. 
	 * 		이 좌표계는 관측자의 기준에서 천체의 위치를 나타내는데 유용하게 쓰인다. 
	 *  <li>적도좌표계(equatorial coordinate system) : 
	 * 		지구의 적도를 연장선으로 바라보는 좌표계이다. 
	 * 		지구의 회전축을 기준으로 북쪽을 천구의 북극, 남쪽을 천구의 남극이라고 하며
	 * 		춘분점으로부터 시계방향으로 천구의 적도를 따라 천체의 발까지 잰각을 적경(right acension),
	 * 		천체의 발부터 천체까지 잰각을 적위(declination)이라고 정의한다. 
	 * 		이 좌표계는 항성(별)의 위치를 나타내는데 쓰인다.
	 * 	<li>황도좌표계(ecliptic coordinate system ) :
	 * 		지구의 공전궤도면이 기준면을 황도면이라고 한다. 황도면에 수직인 선을 기준으로 북쪽을 +, 남쪽으로 -로 한다.
	 * 		보통 태양계의 행성, 소행성, 혜성등의 위치를 나타낼때 쓰는 좌표계이다.
	 * 		지구공전궤도면과 천구의 적도가 만나점을 춘분점, 추분점이라고 하는데 이 중에 승교점(acending note)를 춘분점이라 정의한다. 
	 * 		춘분점으로부터 시계방향으로 황도를 따라   천체의 발까지 잰각을 황경(ecliptic longitude),
	 * 		천체의 발부터 천체까지 잰각을 황위(ecliptic latitude)라고 한다. 
	 * 	<li>은하좌표계(galatic coordinate system ) :
	 * 		우리 은하를 기준으로 삼는 좌표계이다. 은하면이 기준면이고 은하의 중심이 기준좌표이다. 
	 * 		은하의 기준좌표는 은하의 중심인 적경 17h 42.4m, 적위 -28도 55' 로 한다.
	 * 		기준좌표로부터 은하면을따라 시계방향으로 천체의 발까지 잰각을 은경(galatic longitude),
	 * 		천체의 발부터 천체까지 잰각을 은위(galatic latitude)라고 한다. 
	 * </ul>
	 * 
	 * <p>기능구현에 대해</p>
	 * <ul>
	 * 	<li>단순한 공식이 아닌 행렬변환을 이용했다. 단순한 공식을 사용한다면 1개 값 처리에는 유리하지만 여러개를 처리할 때 쓸데없는 계산을 요할 수 있기 때문이다.
	 * 	<li>빠른 계산을 위해 사용할 계수값(황도의 기울기, 관측지점 위도, 지방항성시)을  sin,cos값으로 미리 계산하여 상수화 시켜 사용한다.
	 *  <li>변환행렬은 사용할때 loose하게 만들어진다. 이는 사용하지도 않을 행렬을 미리 만들어 퍼포먼스를 저하시키는 요인을 제거해준다.
	 * 	<li>천문학에서 사용하는 중요 4개 좌표계 변환을 모두 수행하도록 만들었다. 
	 *  <li>이 클래스는 클래스를 객체화해서 사용해도 되며 정적함수를 이용해서 사용해도 된다. 
	 * 		클래스 객체를 이용하면 더욱 빠른 계산이 가능하며 정적함수를 이용하면 사용되는 행렬을 가져다가 재구성이 가능해진다. 
	 * </ul>
	 * 				
	 * @author Yongho,Ji (jidolstar@gmail.com)
	 * @since 2009.04.07
	 * @see Practical astronomy with your calculator. 3rd edition. p45
	 * @example 
	 * <listing version="3.0">
	 * var obliquityOfEcliptic:Number = 23.44; //23.44도. 시간에 따라 변하는 값임 
	 * var latitude:Number = 35; //북위 34도
	 * var localSiderealTime:Number = 3;//3h. 시간에 따라 변하는 값음 
	 * var coordTrans:ALCoordinateTransformation = new ALCoordinateTransformation( obliquityOfEcliptic, latitude, localSiderealTime);
	 * var equVector3DArray:Array = 
	 * 			[ 
	 * 				new ALVector3D( 23.1*ALConstant.H2R, -2.22*ALConstant.D2R, 1, ALVector3D.COORDINATE_TYPE_SPHERICAL ),
	 * 				new ALVector3D( 31.3*ALConstant.H2R, 12.43*ALConstant.D2R, 1, ALVector3D.COORDINATE_TYPE_SPHERICAL ) 
	 * 			];
	 * var horVector3DArray:Array = coordTran아s.Equ2Hor( equVector3DArray );
	 * for ecch( var horVector3D:ALVector3D in horVector3DArray )
	 * {
	 * 		trace( horVector3D.longitude * ALConstant.R2D, horVector3D.latitude * ALConstant.R2D ); //방위각,고도 
	 * }
	 * </listing>
	 */ 
	public class ALCoordinateTransformation
	{
		private var sin_e:Number;
		private var cos_e:Number;
		private var sin_lat:Number;
		private var cos_lat:Number;
		private var sin_lst:Number;
		private var cos_lst:Number; 
		private var epsilon:Number;
		private var lat:Number;
		private var lst:Number;
		
		private var Equ2EclMatrix:ALMatrix3D;	//Equatorial -> Ecliptic
		private var Ecl2EquMatrix:ALMatrix3D;	//Ecliptic -> Equatorial
		private var Equ2HorMatrix:ALMatrix3D;	//Equatorial -> Horizontal 
		private var Hor2EquMatrix:ALMatrix3D;	//Horizontal -> Equatorial
		private var Equ2GalMatrix:ALMatrix3D;	//Equatorial = Galatic
		private var Gal2EquMatrix:ALMatrix3D;	//Galatic -> Equatorial
		
		private var Hor2EclMatrix:ALMatrix3D;	//Horizontal -> Ecliptic
		private var Ecl2HorMatrix:ALMatrix3D;	//Ecliptic -> Horizontal
		private var Gal2HorMatrix:ALMatrix3D;	//Galatic -> Horizontal
		private var Hor2GalMatrix:ALMatrix3D;	//Horizontal -> Galatic
		private var Ecl2GalMatrix:ALMatrix3D;	//Ecliptic -> Galatic
		private var Gal2EclMatrix:ALMatrix3D;	//Galatic -> Ecliptic
		
		/**
		 * 생성자 
		 * @see setCoefficents();
		 */ 
		public function ALCoordinateTransformation( obliquityOfEcliptic:Number, latitude:Number, localSiderealTime:Number )
		{
			setCoefficents( obliquityOfEcliptic, latitude, localSiderealTime );
		}
		
		/**
		 * 계수 설정  
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
  		 */ 
		public function setCoefficents( obliquityOfEcliptic:Number, latitude:Number, localSiderealTime:Number ):void
		{
			//항성시만 변했으면 지평좌표계와 관련있는 행렬만 초기화 한다. 
			if( this.epsilon == obliquityOfEcliptic && this.lat == latitude && this.lst != localSiderealTime )
			{
				Equ2HorMatrix = null;
				Hor2EquMatrix = null;

				Hor2EclMatrix = null;
				Ecl2HorMatrix = null;
				Gal2HorMatrix = null;
				Hor2GalMatrix = null;
			}
			else
			{
				Equ2EclMatrix = null;
				Ecl2EquMatrix = null;
				Equ2HorMatrix = null;
				Hor2EquMatrix = null;
				Gal2EquMatrix = null;
				Equ2GalMatrix = null;
				
				Hor2EclMatrix = null;
				Ecl2HorMatrix = null;
				Gal2HorMatrix = null;
				Hor2GalMatrix = null;
				Ecl2GalMatrix = null;
				Gal2EclMatrix = null;
			}
			
			//황도의 기울기 
			this.epsilon = obliquityOfEcliptic;
			obliquityOfEcliptic = obliquityOfEcliptic * ALConst.D2R;
  			sin_e = Math.sin( obliquityOfEcliptic );
  			cos_e = Math.cos( obliquityOfEcliptic );
  			
  			//관측지점 위도 
			this.lat = latitude;
			latitude = latitude * ALConst.D2R;
			sin_lat = Math.sin( latitude );
			cos_lat = Math.cos( latitude );  			

			//관측지점 기준의 지방항성시 
			this.lst = localSiderealTime;
			localSiderealTime *= ALConst.H2R;
			sin_lst = Math.sin( localSiderealTime );
			cos_lst = Math.cos( localSiderealTime );
		}
		
		/**
		 * 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 주의사항 : degree 단위값이다.
		 */ 
		public function get obliquityOfEcliptic():Number
		{
			return epsilon;
		}
		
		/**
		 * 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다.
		 * 주의사항 : degree 단위값이다.
		 */ 
		public function get latitude():Number
		{
			return lat;
		} 
		
		/**
		 * 관측지점의 시간각(Local Hour Angle)
		 * 주의사항 : hour 단위 값이다.
		 */ 
		public function get localSiderealTime():Number
		{
			return lst;
		} 

		/**
		 * The transformation from equatorial into ecliptical coordinates.
		 * @param 적도좌표계값을 담은 배열. ALVector3D객체 배열이며 적경 (right ascension)과 적위(declination)를 가진다.
		 * @return 황도좌표계값을 담은 배열. AL2DCoordinate객체 배열이며 황경(longitude),황위(latitude)를 가진다.   
		 */ 
		public function Equ2Ecl( equVector3DArray:Array ):Array
		{
			setEqu2EclMatrix();
			return Equ2EclMatrix.multiply3x3ByVector3D( equVector3DArray );
		}
		
		/**
		 * The transformation from ecliptical into equatorial coordinates.
		 * @param 황도좌표계값을 담은 배열. AL2DCoordinate객체 배열이며 황경(longitude),황위(latitude)를 가진다.
		 * @return 적도좌표계값을 담은 배열. ALVector3D객체 배열이며 적경 (right ascension)과 적위(declination)를 가진다.   
		 */ 		
		public function Ecl2Equ( eclVector3DArray:Array ):Array
		{
			setEcl2EquMatrix();
			return Ecl2EquMatrix.multiply3x3ByVector3D( eclVector3DArray );
		}

		/**
		 * The transformation from equatorial into horizontal coordinates.
		 * @param 적도좌표계값을 담은 배열. ALVector3D 객체 배열이며 적경 (right ascension)과 적위(declination)를 가진다.
		 * @return 지평좌표계값을 담은 배열. ALVector3D 객체 배열이며 방위각(azimuth)과 고도(altitude)를 가진다.
		 */ 
		public function Equ2Hor( equVector3DArray:Array ):Array
		{
			setEqu2HorMatrix();
			return Equ2HorMatrix.multiply3x3ByVector3D( equVector3DArray );
		}
		
		/**
		 * The transformation from horizontal into equatorial coordinates.
		 * @param 지평좌표계값을 담은 배열. ALVector3D 객체 배열이며 방위각(azimuth)과 고도(altitude)를 가진다.  
		 * @return 적도좌표계값을 담은 배열. ALVector3D 객체 배열이며 적경 (right ascension)과 적위(declination)를 가진다.
		 */ 
		public function Hor2Equ( horVector3DArray:Array):Array 
		{
			setHor2EquMatrix();
			return Hor2EquMatrix.multiply3x3ByVector3D( horVector3DArray );
		}
		
		/**
		 * The transformation from equatorial into galactic coordinates.
		 * @param 적도좌표계값을 담은 배열. ALVector3D 객체 배열이며 적경 (right ascension)과 적위(declination)를 가진다.
		 * @return 은하좌표계값을 담은 배열. ALVector3D 객체 배열이며 은경(galatic longitude), 은위(galatic latitude)를 가진다.
		 */ 			
		public function Equ2Gal( equVector3DArray:Array ):Array
		{
			setEqu2GalMatrix()
			return Equ2GalMatrix.multiply3x3ByVector3D( equVector3DArray );			
		}
				
		/**
		 * The transformation from galactic into equatorial coordinates.
		 * @param 은하좌표계값을 담은 배열. ALVector3D 객체 배열이며 은경(galatic longitude), 은위(galatic latitude)를 가진다.
		 * @return 적도좌표계값을 담은 배열. ALVector3D 객체 배열이며 적경 (right ascension)과 적위(declination)를 가진다.
		 */ 		
		public function Gal2Equ( galVector3DArray:Array ):Array
		{
			setGal2EquMatrix();
			return Gal2EquMatrix.multiply3x3ByVector3D( galVector3DArray );
		}
		
		/**
		 * The transformation from horizontal into ecliptic coordinates
		 * @param 지평좌표계값을 담은 배열. ALVector3D 객체 배열이며 방위각(azimuth)과 고도(altitude)를 가진다.
		 * @return 황도좌표계값을 담은 배열. AL2DCoordinate객체 배열이며 황경(longitude),황위(latitude)를 가진다.
		 */ 
		public function Hor2Ecl( horVector3DArray:Array ):Array
		{
			setHor2EclMatrix();
			return Hor2EclMatrix.multiply3x3ByVector3D( horVector3DArray );
		}
		
		/**
		 * The transformation from ecliptic into horizontal coordinates
		 * @param 황도좌표계값을 담은 배열. AL2DCoordinate객체 배열이며 황경(longitude),황위(latitude)를 가진다.
		 * @return 지평좌표계값을 담은 배열. ALVector3D 객체 배열이며 방위각(azimuth)과 고도(altitude)를 가진다.
		 */ 
		public function Ecl2Hor( eclVector3DArray:Array ):Array
		{
			setEcl2HorMatrix();
			return Ecl2HorMatrix.multiply3x3ByVector3D( eclVector3DArray );
		}		
		
		/**
		 * The transformation from galatic into horizontal coordinates
		 * @param 은하좌표계값을 담은 배열. ALVector3D 객체 배열이며 은경(galatic longitude), 은위(galatic latitude)를 가진다.
		 * @return 지평좌표계값을 담은 배열. ALVector3D 객체 배열이며 방위각(azimuth)과 고도(altitude)를 가진다.
		 */ 
		public function Gal2Hor( galVector3DArray:Array ):Array
		{
			setGal2HorMatrix();
			return Gal2HorMatrix.multiply3x3ByVector3D( galVector3DArray );
		}
		
		/**
		 * The transformation from horizontal into galatic coordinates
		 * @param 지평좌표계값을 담은 배열. ALVector3D 객체 배열이며 방위각(azimuth)과 고도(altitude)를 가진다.
		 * @return 은하좌표계값을 담은 배열. ALVector3D 객체 배열이며 은경(galatic longitude), 은위(galatic latitude)를 가진다.
		 */ 
		public function Hor2Gal( horVector3DArray:Array ):Array
		{
			setHor2GalMatrix();
			return Hor2GalMatrix.multiply3x3ByVector3D( horVector3DArray );
		}
		
		/**
		 * The transformation from ecliptic into galatic coordinates
		 * @param 황도좌표계값을 담은 배열. AL2DCoordinate객체 배열이며 황경(longitude),황위(latitude)를 가진다.
		 * @return 은하좌표계값을 담은 배열. ALVector3D 객체 배열이며 은경(galatic longitude), 은위(galatic latitude)를 가진다.
		 */ 
		public function Ecl2Gal( eclVector3DArray:Array ):Array
		{
			setEcl2GalMatrix();
			return Ecl2GalMatrix.multiply3x3ByVector3D( eclVector3DArray );
		}
		
		/**
		 * The transformation from galatic into ecliptic coordinates
		 * @param 은하좌표계값을 담은 배열. ALVector3D 객체 배열이며 은경(galatic longitude), 은위(galatic latitude)를 가진다.
		 * @return 황도좌표계값을 담은 배열. AL2DCoordinate객체 배열이며 황경(longitude),황위(latitude)를 가진다.
		 */ 
		public function Gal2Ecl( galVector3DArray:Array ):Array 
		{
			setGal2EclMatrix();
			return Gal2EclMatrix.multiply3x3ByVector3D( galVector3DArray );
		}
		
		public function getEqu2EclMatrix():ALMatrix3D
		{
			setEqu2EclMatrix();
			return Equ2EclMatrix;
		}
		
		public function getEcl2EquMatrix():ALMatrix3D
		{
			setEcl2EquMatrix();
			return Ecl2EquMatrix;
		}
		
		public function getEqu2HorMatrix():ALMatrix3D
		{
			setEqu2HorMatrix();
			return Equ2HorMatrix;
		}
		
		public function getHor2EquMatrix():ALMatrix3D
		{
			setHor2EquMatrix();
			return Hor2EquMatrix;	
		}
		
		public function getEqu2GalMatrix():ALMatrix3D
		{
			setEqu2GalMatrix();
			return Equ2GalMatrix;
		}
		
		public function getGal2EquMatrix():ALMatrix3D
		{
			setGal2EquMatrix();
			return Gal2EquMatrix;	
		}
		
		public function getHor2EclMatrix():ALMatrix3D
		{
			setHor2EclMatrix();
			return Hor2EclMatrix;
		}
		
		public function getEcl2HorMatrix():ALMatrix3D
		{
			setEcl2HorMatrix();
			return Ecl2HorMatrix;
		}
		
		public function getGal2HorMatrix():ALMatrix3D
		{
			setGal2HorMatrix();
			return Gal2HorMatrix;
		}
		
		public function getHor2GalMatrix():ALMatrix3D
		{
			setHor2GalMatrix();
			return Hor2GalMatrix;
		}
		
		public function getEcl2GalMatrix():ALMatrix3D
		{
			setEcl2GalMatrix();
			return Ecl2GalMatrix;
		}
		
		public function getGal2EclMatrix():ALMatrix3D
		{
			setGal2EclMatrix();
			return Gal2EclMatrix;
		}
		
		
		/**
		 * @private
		 */ 
		private function setEqu2EclMatrix():void
		{
			if( Equ2EclMatrix == null )
			{
				Equ2EclMatrix = new ALMatrix3D( 1, 0.0, 0.0,
					  							0.0, cos_e, sin_e,
					  							0.0, -sin_e, cos_e  );
			}				
		}
		
		/**
		 * @private
		 */ 
		private function setEcl2EquMatrix():void
		{
			if( Ecl2EquMatrix == null )
			{
				Ecl2EquMatrix = new ALMatrix3D( 1, 0.0, 0.0,
					  							0.0, cos_e, -sin_e,
					  							0.0, sin_e, cos_e  );
			}				
		}
		
		/**
		 * @private
		 */ 
		private function setEqu2HorMatrix():void
		{
			if( Equ2HorMatrix == null )
			{
				Equ2HorMatrix = new ALMatrix3D( -sin_lat * cos_lst,	-sin_lat * sin_lst, cos_lat,
												-sin_lst, cos_lst, 0.0,
												cos_lat * cos_lst, cos_lat * sin_lst, sin_lat );
			}			
		}
		
		/**
		 * @private
		 */ 
		private function setHor2EquMatrix():void
		{
			if( Hor2EquMatrix == null )
			{
				Hor2EquMatrix = new ALMatrix3D( -cos_lst * sin_lat,	-sin_lst,	cos_lst * cos_lat,
												-sin_lst * sin_lat,	cos_lst,	sin_lst * cos_lat,
												cos_lat,			0.0,		sin_lat );
			}
		}
		
		/**
		 * @private
		 */ 
		private function setEqu2GalMatrix():void
		{
			if( Equ2GalMatrix == null )
			{
				Equ2GalMatrix = new ALMatrix3D( -0.0669887, -0.8727558, -0.4835389,
				      							0.4927285, -0.4503470, 0.7445846,
				      							-0.8676008, -0.1883746, 0.4601998);				
			}		
		}
		
		/**
		 * @private
		 */ 
		private function setGal2EquMatrix():void
		{
			if( Gal2EquMatrix == null )
			{
				Gal2EquMatrix = new ALMatrix3D( -0.0669887, 0.4927285, -0.8676008, 
												-0.8727558, -0.4503470, -0.1883746, 
												-0.4835389, 0.7445846, 0.4601998 );
			}			
		}
		
		/**
		 * @private
		 */ 
		private function setHor2EclMatrix():void
		{
			if( Hor2EclMatrix == null )
			{
				setHor2EquMatrix();
				setEqu2EclMatrix();
				Hor2EclMatrix = ALMatrix3D.multiplyMatrix( Equ2EclMatrix, Hor2EquMatrix );
			}
		}
		
		/**
		 * @private
		 */ 
		private function setEcl2HorMatrix():void
		{
			if( Ecl2HorMatrix == null )
			{
				setEqu2HorMatrix();
				setEcl2EquMatrix();
				Ecl2HorMatrix = ALMatrix3D.multiplyMatrix( Equ2HorMatrix, Ecl2EquMatrix );
			}
		}
		
		/**
		 * @private
		 */ 
		private function setGal2HorMatrix():void
		{
			if( Gal2HorMatrix == null )
			{
				setGal2EquMatrix();
				setEqu2HorMatrix();
				Gal2HorMatrix = ALMatrix3D.multiplyMatrix( Equ2HorMatrix, Gal2EquMatrix );
			}
		}
		
		/**
		 * @private
		 */ 
		private function setHor2GalMatrix():void
		{
			if( Hor2GalMatrix == null )
			{
				setHor2EquMatrix();
				setEqu2GalMatrix();
				Hor2GalMatrix = ALMatrix3D.multiplyMatrix( Equ2GalMatrix, Hor2EquMatrix );
			}
		}
		
		/**
		 * @private
		 */ 
		private function setEcl2GalMatrix():void
		{
			if( Ecl2GalMatrix == null )
			{
				setEcl2EquMatrix();
				setEqu2GalMatrix();
				Ecl2GalMatrix = ALMatrix3D.multiplyMatrix( Equ2GalMatrix, Ecl2EquMatrix );
			}
		}
		
		/**
		 * @private
		 */ 
		private function setGal2EclMatrix():void
		{
			if( Gal2EclMatrix == null )
			{
				setGal2EquMatrix();
				setEqu2EclMatrix();
				Gal2EclMatrix = ALMatrix3D.multiplyMatrix( Equ2EclMatrix, Gal2EquMatrix );
			}
		}
		
		/**
		 * Transformation matrix from equatorial into ecliptical coordinates.
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @return 
		 */ 
		static public function getEqu2EclMatrix( obliquityOfEcliptic:Number ):ALMatrix3D
		{
			//황도의 기울기 
			obliquityOfEcliptic = obliquityOfEcliptic * ALConst.D2R;
  			var sin_e:Number = Math.sin( obliquityOfEcliptic );
  			var cos_e:Number = Math.cos( obliquityOfEcliptic );
  						
			return new ALMatrix3D( 1, 0.0, 0.0,
			  						0.0, cos_e, sin_e,
			  						0.0, -sin_e, cos_e  );
		}
		
		/**
		 * Transformation matrix from ecliptical into equatorial coordinates.
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @return 
		 */ 
		static public function getEcl2EquMatrix( obliquityOfEcliptic:Number ):ALMatrix3D
		{
			//황도의 기울기 
			obliquityOfEcliptic = obliquityOfEcliptic * ALConst.D2R;
  			var sin_e:Number = Math.sin( obliquityOfEcliptic );
  			var cos_e:Number = Math.cos( obliquityOfEcliptic );
  									
			return new ALMatrix3D( 1, 0.0, 0.0,
		  							0.0, cos_e, -sin_e,
		  							0.0, sin_e, cos_e  );	
		}
		
		/**
		 * Transformation matrix from equatorial into horizontal coordinates.
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
		 * @return 
		 */ 
		static public function getEqu2HorMatrix( latitude:Number, localSiderealTime:Number ):ALMatrix3D
		{
  			//관측지점 위도 
			latitude = latitude * ALConst.D2R;
			var sin_lat:Number = Math.sin( latitude );
			var cos_lat:Number = Math.cos( latitude );  			

			//관측지점 기준의 지방항성시 
			localSiderealTime *= ALConst.H2R;
			var sin_lst:Number = Math.sin( localSiderealTime );
			var cos_lst:Number = Math.cos( localSiderealTime );
			
			return new ALMatrix3D( -sin_lat * cos_lst,	-sin_lat * sin_lst, cos_lat,
								-sin_lst, cos_lst, 0.0,
								cos_lat * cos_lst, cos_lat * sin_lst, sin_lat );
		}
		
		/**
		 * Transformation matrix from horizontal into equatorial coordinates.
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
		 * @return 
		 */ 		
		static public function getHor2EquMatrix( latitude:Number, localSiderealTime:Number ):ALMatrix3D
		{
  			//관측지점 위도 
			latitude = latitude * ALConst.D2R;
			var sin_lat:Number = Math.sin( latitude );
			var cos_lat:Number = Math.cos( latitude );  			

			//관측지점 기준의 지방항성시 
			localSiderealTime *= ALConst.H2R;
			var sin_lst:Number = Math.sin( localSiderealTime );
			var cos_lst:Number = Math.cos( localSiderealTime );
			
			return new ALMatrix3D( -cos_lst * sin_lat,	-sin_lst,	cos_lst * cos_lat,
								-sin_lst * sin_lat,	cos_lst,	sin_lst * cos_lat,
								cos_lat,			0.0,		sin_lat );	
		}
		
		/**
		 * Transformation matrix from equatorial into galatic coordinates.
		 * @return 
		 */ 			
		static public function getEqu2GalMatrix():ALMatrix3D
		{
			return new ALMatrix3D( -0.0669887, -0.8727558, -0.4835389,
      							0.4927285, -0.4503470, 0.7445846,
      							-0.8676008, -0.1883746, 0.4601998);	
		}
		
		/**
		 * Transformation matrix from galatic into equatorial coordinates.
		 * @return 
		 */ 			
		static public function getGal2EquMatrix():ALMatrix3D
		{
			return new ALMatrix3D( -0.0669887, 0.4927285, -0.8676008, 
								-0.8727558, -0.4503470, -0.1883746, 
								-0.4835389, 0.7445846, 0.4601998 );
		}
		
		/**
		 * Transformation matrix from horizontal into ecliptical coordinates.
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
		 * @return
		 */ 
		static public function getHor2EclMatrix( obliquityOfEcliptic:Number, latitude:Number, localSiderealTime:Number ):ALMatrix3D
		{
			var Hor2EquMatrix:ALMatrix3D = getHor2EquMatrix( latitude, localSiderealTime );
			var Equ2EclMatrix:ALMatrix3D = getEqu2EclMatrix( obliquityOfEcliptic );
			return ALMatrix3D.multiplyMatrix( Equ2EclMatrix, Hor2EquMatrix );			
		}
		
		/**
		 * Transformation matrix from ecliptical into horizontal coordinates.
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
		 * @return
		 */ 		
		static public function getEcl2HorMatrix( obliquityOfEcliptic:Number, latitude:Number, localSiderealTime:Number ):ALMatrix3D
		{
			var Equ2HorMatrix:ALMatrix3D = getEqu2HorMatrix( latitude, localSiderealTime );
			var Ecl2EquMatrix:ALMatrix3D = getEcl2EquMatrix( obliquityOfEcliptic );
			return ALMatrix3D.multiplyMatrix( Equ2HorMatrix, Ecl2EquMatrix );			
		}
		
		/**
		 * Transformation matrix from galatic into horizontal coordinates.
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
		 * @return 
		 */ 
		static public function getGal2HorMatrix( latitude:Number, localSiderealTime:Number ):ALMatrix3D
		{
			var Gal2EquMatrix:ALMatrix3D = getGal2EquMatrix();
			var Equ2HorMatrix:ALMatrix3D = getEqu2HorMatrix( latitude, localSiderealTime );
			return ALMatrix3D.multiplyMatrix( Equ2HorMatrix, Gal2EquMatrix );			
		}
		
		/**
		 * Transformation matrix from horizontal into galatic coordinates.
		 * @param latitude 관측지점의 위도. 북반구는 +, 남반구는 -값을 가진다. 이 값은 degree값이다.
		 * @param localSideralTime 관측지점 기준의 지방항성시. 이 값은 Hour값이다. 
		 * @return 
		 */ 
		static public function getHor2GalMatrix( latitude:Number, localSiderealTime:Number ):ALMatrix3D
		{
			var Hor2EquMatrix:ALMatrix3D = getHor2EquMatrix( latitude, localSiderealTime ); 
			var Equ2GalMatrix:ALMatrix3D = getEqu2GalMatrix();
			return ALMatrix3D.multiplyMatrix( Equ2GalMatrix, Hor2EquMatrix );
		}
		
		/**
		 * Transformation matrix from ecliptic into galatic coordinates.
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @return
		 */ 
		static public function getEcl2GalMatrix( obliquityOfEcliptic:Number ):ALMatrix3D
		{
			var Ecl2EquMatrix:ALMatrix3D = getEcl2EquMatrix( obliquityOfEcliptic );
			var Equ2GalMatrix:ALMatrix3D = getEqu2GalMatrix();
			return ALMatrix3D.multiplyMatrix( Equ2GalMatrix, Ecl2EquMatrix );
		}
		
		/**
		 * Transformation matrix from galatic into ecliptic coordinates.
		 * @param obliquityOfEcliptic 황도의 기울기(obliquity of the ecliptic), 이 각은 황도와 천구의 적도사이의 각이다. 
		 * 							정확한 변환을 요구하는 경우 장동(nutation), 광행차(aberration)를 고려한 값이 될 수 있다. 
		 * 							degree값이다.   
		 * @return
		 */ 
		static public function getGal2EclMatrix(obliquityOfEcliptic:Number ):ALMatrix3D
		{
			var Gal2EquMatrix:ALMatrix3D = getGal2EquMatrix();
			var Equ2EclMatrix:ALMatrix3D = getEqu2EclMatrix( obliquityOfEcliptic );
			return ALMatrix3D.multiplyMatrix( Equ2EclMatrix, Gal2EquMatrix );
		}		
	}
}